題目:
判斷一個字串在忽略非英數字元(非字母與非數字)以及大小寫差異後,是否為回文
範例:
Example 1:
Input: s = "A man, a plan, a canal: Panama"
Output: true
Explanation: "amanaplanacanalpanama" is a palindrome.
Example 2:
Input: s = "race a car"
Output: false
Explanation: "raceacar" is not a palindrome.
Example 3:
Input: s = " "
Output: true
Explanation: s is an empty string "" after removing
non-alphanumeric characters.
Since an empty string reads the same forward and
backward, it is a palindrome.
想法:
先順著讀,並把標點符號、空格去除——>用雙指標讀取
優化:利用函式直接判斷,並跳過非英數字元
程式碼:
class Solution {
public boolean isPalindrome(String s) {
//初始化左右指標
int l = 0;
int r = s.length() - 1;
while (l < r) {
while (l < r && !Character.isLetterOrDigit(s.charAt(l))) { //跳過左邊的非英數字元
l++;
}
while (l < r && !Character.isLetterOrDigit(s.charAt(r))) { //跳過右邊的非英數字元
r--;
}
//比較雙方指向的字元(轉為小寫再比較以忽略大小寫)
if (Character.toLowerCase(s.charAt(l)) != Character.toLowerCase(s.charAt(r))) {
return false; //若不相等則不是回文
}
//兩字元相等 → 各自向內移動一格
l++;
r--;
}
//若檢查完成皆相等 → 是回文
return true;
}
}
Character.isLetterOrDigit() ——>標準函式判斷字是否為英文字母或數字
實際操作:
字串:"No lemon, no melon!"
l=0 ('N'), r=18 ('!')
0:N 1:o 2:' ' 3:l 4:e 5:m 6:o 7:n 8:, 9:' '
10:n 11:o 12:' ' 13:m 14:e 15:l 16:o 17:n 18:!
Step 1:
右邊是 !(非英數),跳過 → r=17(現在為 'n')
比較 s[0]='N' 與 s[17]='n'(轉小寫比較:'n' vs 'n')→ 相等
移動:l=1, r=16
Step 2:
l=1 ('o'), r=16 ('o')
比較 'o' vs 'o' → 相等
移動:l=2, r=15
Step 3:
l=2 是空白(非英數),跳過 → l=3 ('l')
r=15 ('l')
比較 'l' vs 'l' → 相等
移動:l=4, r=14
Step 4:
l=4 ('e'), r=14 ('e') → 比較 'e' vs 'e' → 相等
移動:l=5, r=13
Step 5:
l=5 ('m'), r=13 ('m') → 比較 'm' vs 'm' → 相等
移動:l=6, r=12
Step 6:
l=6 ('o'), r=12 是空白,跳過 → r=11 ('o')
比較 'o' vs 'o' → 相等
移動:l=7, r=10
Step 7:
l=7 ('n'), r=10 ('n') → 比較 'n' vs 'n' → 相等
移動:l=8, r=9
Step 8:
l=8 是 ','(非英數),跳過 → l=9
現在 l=9、r=9(指標相遇,l >= r,迴圈結束)
結果:ture